package cn.itcast.service.cargo.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.itcast.dao.cargo.*;
import cn.itcast.domain.cargo.*;
import cn.itcast.domain.vo.ExportProductResult;
import cn.itcast.domain.vo.ExportProductVo;
import cn.itcast.domain.vo.ExportResult;
import cn.itcast.domain.vo.ExportVo;
import cn.itcast.service.cargo.ExportService;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.zookeeper.data.Id;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

@Service
public class ExportServiceImpl implements ExportService {

    @Autowired
    private ExportDao exportDao; // 报运dao

    @Autowired
    private ExportProductDao exportProductDao;//报运单商品dao

    @Autowired
    private ExtEproductDao extEproductDao;  //报运单附件Dao

    @Autowired
    private ContractDao contractDao; // 合同dao

    @Autowired
    private ContractProductDao contractProductDao; //合同货物dao

    @Autowired
    private ExtCproductDao extCproductDao;  //合同附件Dao

    //保存
    public void save(Export export) {

        // i.生成报运单
        // 1.设置报运单id
        export.setId(IdUtil.simpleUUID());

        // 2.根据合同主键id，查询合同列表
        String[] contractArray = export.getContractIds().split(",");
        ContractExample contractExample = new ContractExample();
        contractExample.createCriteria().andIdIn(Arrays.asList(contractArray)); //  where id in (1,2,3);
        List<Contract> contractList = contractDao.selectByExample(contractExample);

        // 3.遍历合同列表，拼接合同号字符串
        String customerContract = "";
        Integer proNum = 0;
        Integer extNum = 0;
        for (Contract contract : contractList) {
            customerContract += contract.getContractNo() + " "; // 拼接合同号

            proNum += contract.getProNum(); // 追加货物种类数
            extNum += contract.getExtNum();// 追加附件种类数

            // 修改合同状态
            contract.setState(2); // 已报运
            contractDao.updateByPrimaryKeySelective(contract);
        }
        // 4.将合同号设置报运单
        export.setCustomerContract(customerContract);

        // 5.设置报运单货物种类和附件种类
        export.setProNum(proNum);
        export.setExtNum(extNum);
        // 6.设置报运单状态
        export.setState(0); // 草稿

        exportDao.insertSelective(export);

        // ii.将所有合同的货物对象封装到 报运单商品对象 （一对一）
        // 1.根据合同id查询货物列表
        ContractProductExample cpExample = new ContractProductExample();
        cpExample.createCriteria().andContractIdIn(Arrays.asList(contractArray));
        List<ContractProduct> cpList = contractProductDao.selectByExample(cpExample);
        // 2.遍历货物列表，封装商品对象
        for (ContractProduct cp : cpList) {
            // 创建报运单商品对象
            ExportProduct ep = new ExportProduct();
            // 可以使用糊涂工具类完成对象之间属性复制
            BeanUtil.copyProperties(cp, ep);
            // 手动指定商品id、和关联报运单的id
            ep.setId(IdUtil.simpleUUID());
            ep.setExportId(export.getId());
            // 保存商品对象
            exportProductDao.insertSelective(ep);
            // iii。将所有合同附件对象封装到 报运单附件对象 （一对一）
            // 1.根据货物id，查询货物附件列表
            ExtCproductExample extcExample = new ExtCproductExample();
            extcExample.createCriteria().andContractProductIdEqualTo(cp.getId());
            List<ExtCproduct> extcList = extCproductDao.selectByExample(extcExample);
            // 2.遍历货物附件
            for (ExtCproduct extc : extcList) {
                // 创建商品附件对象
                ExtEproduct exte = new ExtEproduct();
                // 可以使用糊涂工具类完成对象之间属性复制
                BeanUtil.copyProperties(extc, exte);
                // 手动指定 id、报运单id、商品id
                exte.setId(IdUtil.simpleUUID());
                exte.setExportId(export.getId());
                exte.setExportProductId(ep.getId());
                // 保存附件对象
                extEproductDao.insertSelective(exte);
            }
        }

    }

    //更新
    public void update(Export export) {
        // 1.更新报运单
        exportDao.updateByPrimaryKeySelective(export);
        // 2.更新报运单商品列表
        List<ExportProduct> list = export.getExportProducts();
        if (list != null && list.size() > 0) {
            for (ExportProduct ep : list) {
                exportProductDao.updateByPrimaryKeySelective(ep);
            }
        }
    }

    //删除
    public void delete(String id) {

    }

    //根据id查询
    public Export findById(String id) {
        return exportDao.selectByPrimaryKey(id);
    }

    //分页
    public PageInfo findByPage(int pageNum, int pageSize, ExportExample example) {
        PageHelper.startPage(pageNum, pageSize);
        List<Export> list = exportDao.selectByExample(example);
        return new PageInfo(list);
    }

    @Override
    public void exportE(String id) {
        // 1.根据id查询报运单对象
        Export export = exportDao.selectByPrimaryKey(id);

        // 2.根据报运单id查询商品列表
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> epList = exportProductDao.selectByExample(exportProductExample);

        // 3.将export对象封装到exportVo对象
        ExportVo exportVo = new ExportVo();
        BeanUtil.copyProperties(export, exportVo);
        exportVo.setExportId(export.getId()); // 报运单id

        // 4.将export商品对象封装到exportProductVo对象中
        List<ExportProductVo> epvList = new ArrayList<>();
        for (ExportProduct ep : epList) {
            ExportProductVo epv = new ExportProductVo(); // 海关商品标准对象
            BeanUtil.copyProperties(ep, epv);
            epv.setEid(export.getId()); // 报运单id
            epv.setExportProductId(ep.getId()); // 商品id

            epvList.add(epv);

        }
        exportVo.setProducts(epvList);

        // 5.使用ws的客户端发送电子报运
        WebClient sendExportVo = WebClient.create("http://localhost:8088/ws/export/user");
        sendExportVo.post(exportVo);

        // 6.修改报运单状态
        export.setState(1); // 已上报
        exportDao.updateByPrimaryKeySelective(export);
    }

    public void changeExportEResult(String id) {
        // 1.调用ws客户端根据报运单id查询报运结果
        WebClient findExportResult = WebClient.create("http://localhost:8088/ws/export/user/" + id);
        ExportResult exportResult = findExportResult.get(ExportResult.class);
        // 2.同步到数据库
        if (exportResult != null) {
            // 3.同步报运单
            Export export = new Export();
            export.setId(exportResult.getExportId());
            export.setState(exportResult.getState()); // 报运单状态
            //  export.setRemark(exportResult.getRemark()); //  海关的审核说明
            exportDao.updateByPrimaryKeySelective(export);
            //  4.同步报运单商品
            Set<ExportProductResult> products = exportResult.getProducts();
            if (CollectionUtil.isNotEmpty(products)) {
                for (ExportProductResult product : products) {
                    ExportProduct exportProduct = new ExportProduct();
                    exportProduct.setId(product.getExportProductId()); // 商品id
                    exportProduct.setTax(product.getTax()); // 商品含税价
                    exportProductDao.updateByPrimaryKeySelective(exportProduct);
                }
            }
        }
    }

    public List<Export> findAll(ExportExample example) {
        return exportDao.selectByExample(example);
    }

}
